home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / GNUUCP_2 / SOURCE / SYSDEP.MAC < prev    next >
Text File  |  1989-07-31  |  8KB  |  344 lines

  1. /*
  2.  * @(#)sysdep.mac 1.2 87/09/23    Copyright 1987 Free Software Foundation, Inc.
  3.  *
  4.  * Copying and use of this program are controlled by the terms of the
  5.  * GNU Emacs General Public License.
  6.  */
  7.  
  8. #ifndef lint
  9. char sysdep_version[] = "@(#)sysdep.mac gnuucp Version hoptoad-1.2";
  10. #endif
  11.  
  12. /*
  13.  * Created 22 September 1987 by John Gilmore, 
  14.  * using code from sun!seismo!psc!jsl (John Labovitz).
  15.  * His comments:
  16.  
  17.     1. Logging cleanup.  It makes it somewhat easier to make the
  18.        right time and date for whatever OS you're using.  I made it
  19.        more modular.
  20.     2. Changes in the login routine to let it be more like real Unix
  21.        systems.  I made a special routine that reads a line from the
  22.        input port, and *then* checks it, instead of only checking each
  23.        character as it comes in.  Also, it handles ^D, which my Unix
  24.        systems uses to make sure there's a prompt.  Doesn't handle break.
  25.  
  26. This needs some more work on the Mac side, like letting the user abort
  27. uuslave.  Right now you have to reset the machine!
  28.  
  29. Hope this is useful.  I'm really interesting in running this thing, although
  30. I'm not quite sure how I'm going to configure it (like how to read mail on
  31. the Mac).  But soon I'll be "potomac!sly!jsl".  What I might do is actually
  32. run this as a server on a PC, connected to the Unix machine via RS232, then
  33. write a program on the Mac that can access the PC via Appletalk (aon the
  34. MacBridge card) and get the mail.  That way, any of our 30 macs can get mail
  35. without being connected to Unix... Dreams.
  36.  
  37.  */
  38.  
  39. #include "includes.h"
  40. #include "uucp.h"
  41. #include "sysdep.h"
  42.  
  43. #define inPortName "\p.AIn"        /* modem input port */
  44. #define outPortName "\p.AOut"        /* modem output port */
  45.  
  46. int inRefNum, outRefNum;
  47.  
  48. #define    CONTROL    "gnuucp.ctl"
  49.  
  50. /*
  51.  * Exported variables
  52.  */
  53. char     sysdep_control[] = CONTROL;
  54.  
  55. /*
  56.  * Open the serial line for an incoming call.
  57.  * Argument of NULL or empty string means stdin.
  58.  * FIXME, baud rate should be settable here?
  59.  */
  60. int
  61. openline(ttynam, baud)
  62.     char    *ttynam;
  63.     int    baud;
  64. {
  65.  
  66.     if (OpenDriver(inPortName, &inRefNum) != noErr)
  67.         return(EOF);
  68.     
  69.     if (OpenDriver(outPortName, &outRefNum) != noErr)
  70.         return(EOF);
  71.     
  72.     return(0);
  73. }
  74.  
  75. /*
  76.  * Open the serial line for an outgoing call.
  77.  */
  78. int
  79. openout(ttynam, baud)
  80.     char    *ttynam;
  81.     int    baud;
  82. {
  83.  
  84.     abort();        /* FIXME, not written */
  85.  
  86.     return SUCCESS;
  87. }
  88.  
  89. /*
  90.  * Basement level I/O routines
  91.  *
  92.  * xwrite() writes a character string to the serial port
  93.  * xgetc() returns a character from the serial port, or an EOF for timeout.
  94.  * sigint() restores the state of the serial port on exit.
  95.  * hangup() hangs up the serial port (e.g. drop DTR).
  96.  */
  97.  
  98. void
  99. sigint()
  100. {
  101.     return 0;        /* No-op on mac, it seems there's no way
  102.                    to interrupt it! */
  103. }
  104.  
  105. xwrite(dummy, buf, ctr)
  106. int dummy;
  107. char *buf;
  108. int ctr;
  109. {
  110.     long count;
  111.     
  112.     count = ctr;
  113.     
  114.     if (FSWrite(outRefNum, &count, buf) != noErr)
  115.         return(EOF);
  116.  
  117.     return((int)count);
  118. }
  119.  
  120.  
  121. xgetc()
  122. {
  123.     char data;
  124.     long count;
  125.     long i;
  126.     
  127.     i = TickCount() + (BYTE_TIMEOUT * 60L);
  128.     count = 0;
  129.     
  130.     while (TickCount() < i) {
  131.         SerGetBuf(inRefNum, &count);
  132.         
  133.         if (count > 0) {
  134.             count = 1;    /* make sure we only read one byte */
  135.             
  136.             if (FSRead(inRefNum, &count, &data) != noErr)
  137.                 return(EOF);
  138.  
  139.             return(data & 0xFF);
  140.         }
  141.     }
  142.     
  143.     return(EOF);
  144. }
  145.  
  146. /*
  147.  * hangup(): hang up the 'fone.
  148.  */
  149. int
  150. hangup()
  151. {
  152.  
  153.     abort();    /* FIXME -- write this for Mac */
  154.     sleep(2);        /* To be sure DTR stays down that long */
  155. }
  156.  
  157.  
  158. /*
  159.  * Create a temporary file name for receiving a file into.
  160.  * "name" is the name we will actually eventually want to use for the file.
  161.  * We currently ignore it, but some OS's that can't move files around
  162.  * easily might want to e.g. put the temp file into the same directory
  163.  * that this file is going into.
  164.  *
  165.  * FIXME:
  166.  * This interface should be able to return a "possible" filename, and
  167.  * be re-called if the name is already in use, to get another.
  168.  * This avoids checking here whether the name is good -- saving system calls.
  169.  */
  170. char *
  171. temp_filename(name)
  172.     register char *name;
  173. {
  174.     static char tname[NAMESIZE];
  175.  
  176.     if (ourpid == 0)
  177.         ourpid = getpid();
  178.     (void) sprintf(tname, "TM.u%d", ourpid);
  179.     DEBUG(7, "Using temp file %s\n", tname);
  180.     return tname;
  181. }
  182.  
  183.  
  184. /*
  185.  * Transform a filename from a uucp packet (in Unix format) into a local
  186.  * filename that will work in the local file system.
  187.  *
  188.  * This is a real hack; it puts all the files into one big directory.
  189.  * Everything.  Yuk.
  190.  */
  191. char *
  192. munge_filename(name)
  193.     register char *name;
  194. {
  195.     register char *p;
  196.     static char buffer[NAMESIZE+SLOP];
  197.     int len, hostlen;
  198.  
  199.     DEBUG(7, "Munge_filename  input: %s\n", name);
  200.  
  201.     for (p = name + strlen(name); p != name && *(p-1) != '/'; p--) ;
  202.  
  203.     DEBUG(7, "Munge_filename output: %s\n", p);
  204.     return p;
  205. }
  206.  
  207. /*
  208.  * Uucp work queue scan.
  209.  *
  210.  * gotsome = work_scan(hostname, type);
  211.  * workfile = work_next();
  212.  * void work_done();
  213.  */
  214.  
  215. /*
  216.  * Local variables of the work queue scanner -- not visible to outsiders
  217.  *
  218.  * Workhost and worktype are always null-terminated; keeping their lengths
  219.  * is just a performance hack.  Workprefix is NOT null terminated; various
  220.  * people copy things after it and use the whole string.  Workprefix is
  221.  * exactly workplen long; to append something, strcpy(workprefix+workplen, ...)
  222.  */
  223. #define MAX_TYPE    10
  224. static DIR    *workdir = (DIR *)NULL;
  225. static struct dirent    *workfile;
  226. static char    workhost[MAX_HOST+1];
  227. static int    workhlen;
  228. static char    worktype[MAX_TYPE+1];
  229. static int    worktlen;
  230. static char    workfirst = 0;
  231. /* FIXME, at the moment this can be local to work_scan() */
  232. static char    workprefix[MAX_TYPE+1+MAX_HOST+1+MAX_TYPE+1+MAX_HOST+6+SLOP];
  233.         /*       D        . hoptoad  / D        . hoptoad  N1234\0 */
  234. static int    workplen;
  235.  
  236. void
  237. work_done()
  238. {
  239.     if (workdir)
  240.         closedir(workdir);
  241.     workdir = (DIR *) NULL;
  242.     workfile = (struct dirent *) NULL;
  243.     workfirst = 0;
  244. }
  245.  
  246.  
  247. int
  248. work_scan(host, type)
  249.     char *host;
  250.     char *type;
  251. {
  252.     char *p;
  253.  
  254.     if (!host)
  255.         host = "";
  256.  
  257.     /* If called twice in a row, don't thrash the disk again */
  258.     if (strcmp(workhost, host) == SAME &&
  259.         strcmp(worktype, type) == SAME && workfile)
  260.         return 1;
  261.  
  262.     if (workdir) work_done();        /* Clean up prev call */
  263.  
  264.     workfirst = 1;                /* Initialize for work_next */
  265.     workhlen = strlen(host);
  266.     if (workhlen > sizeof (workhost) -1) abort();
  267.     strcpy(workhost, host);
  268.     if (workhlen > 7) workhlen = 7;        /* Unix uucp limit */
  269.     worktlen = strlen(type);
  270.     if (worktlen > sizeof (worktype) -1) abort();
  271.     strcpy(worktype, type);
  272.  
  273.     /* Figure out which subdirectory this class of files is in. */
  274.     /* FIXME: doesn't handle "all D. files" since D.myname is separate. */
  275.     sprintf(workprefix, "%s.%s", worktype, workhost);
  276.     p = munge_filename(workprefix);
  277.     strcpy(workprefix, p);
  278.     p = index(workprefix, '/');
  279.     if (p)
  280.         workplen = 1 + p - workprefix;    /* Prefix ends after '/' */
  281.     else
  282.         workplen = 0;        /* No / in munged; hence no dir */
  283.     workprefix[workplen] = '\0';
  284.     DEBUG(7, "Work prefix is =%s=\n", workprefix);
  285.  
  286.     strcpy(workprefix+workplen, ".");
  287.     workdir = opendir(workprefix);    /* Open whatever directory */
  288.     if (workdir == NULL) {
  289.         DEBUG(0, "Can't open queue directory %s\n", workprefix);
  290.         return 0;            /* No work */
  291.     }
  292.  
  293.     return work_look();
  294. }
  295.  
  296.  
  297. static int
  298. work_look()
  299. {
  300.     int len;
  301.  
  302.     for (;;) {
  303.         workfile = readdir(workdir);
  304.         if (workfile == NULL) {
  305.             DEBUG(7, "work_look readdir null\n", 0);
  306.             work_done();
  307.             return 0;        /* No work */
  308.         }
  309.         DEBUG(7, "work_look readdir %s\n", workfile->d_name);
  310.  
  311.         /* Is it the right type? */
  312.         if (strncmp(workfile->d_name, worktype, worktlen) == SAME
  313.             && workfile->d_name[worktlen] == '.') {
  314.             /* see if it matches the hostname */
  315.             len = strlen(workfile->d_name);
  316.             /*         "C"        "." "hoptoad" "Xnnnn" */
  317.             if (workhlen == 0 || 
  318.                 (len == worktlen + 1 + workhlen + 5 && 
  319.                  !strncmp(workhost, workfile->d_name+2, workhlen))
  320.                ) {
  321.                 /* Found an entry! */
  322.                 /* FIXME, check grade letter! */
  323.                 DEBUG(7, "work_look found it!\n", 0);
  324.                 return 1;    /* Found work */
  325.             }
  326.         }
  327.     }
  328.     /* NOTREACHED */
  329. }
  330.  
  331.  
  332. char *
  333. work_next()
  334. {
  335.  
  336.     if (!workfirst) {
  337.         if (!workfile || !work_look())
  338.             return (char *)NULL;
  339.     }
  340.     workfirst = 0;
  341.  
  342.     return workfile->d_name;
  343. }
  344.